package com.ruyuan.commodity.common.mamager.impl;

import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruyuan.commodity.model.goods.dos.GoodsDO;
import com.ruyuan.commodity.model.goodssearch.GoodsWordsDO;
import com.ruyuan.commodity.model.goodssearch.enums.GoodsWordsType;
import com.ruyuan.commodity.mq.MqMessageSenderFactory;
import com.ruyuan.commodity.enums.MsgTypeEnums;
import com.ruyuan.commodity.open.api.model.common.WebPage;
import com.ruyuan.commodity.common.mamager.GoodsWordsManager;
import com.ruyuan.commodity.common.mapper.GoodsMapper;
import com.ruyuan.commodity.common.mapper.GoodsWordsMapper;
import com.ruyuan.commodity.exception.ServiceException;
import com.ruyuan.commodity.open.api.model.errorcode.GoodsErrorCode;
import com.ruyuan.commodity.utils.PageConvert;
import com.ruyuan.commodity.utils.PinYinUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 商品分词Manager
 */
@Service
public class GoodsWordsManagerImpl implements GoodsWordsManager {

    /**
     * 商品分词的mapper组件
     */
    @Autowired
    private GoodsWordsMapper goodsWordsMapper;
    /**
     * 商品管理的mapper组件
     */
    @Autowired
    private GoodsMapper goodsMapper;
    /**
     * 发送MQ消息的组件
     */
    @Autowired
    private MqMessageSenderFactory mqMessageSenderFactory;

    /**
     * 新增搜索提示次
     * @param word 分词
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addWord(String word) {

        //查询是否存在该分词
        Integer count = this.goodsWordsMapper.selectCount(new QueryWrapper<GoodsWordsDO>().eq("words", word));
        if (count > 0) {
            throw new ServiceException(GoodsErrorCode.E310.code(), "提示词【" + word + "】已存在");
        }
        //创建入库对象
        GoodsWordsDO goodsWordsDO = new GoodsWordsDO();
        goodsWordsDO.setGoodsNum(0L);
        goodsWordsDO.setQuanpin(PinyinUtil.getPinyin(word));
        goodsWordsDO.setSort(0);
        goodsWordsDO.setSzm(PinYinUtil.getPinYinHeadChar(word));
        goodsWordsDO.setType(GoodsWordsType.PLATFORM.name());
        goodsWordsDO.setWords(word);

        goodsWordsMapper.insert(goodsWordsDO);

        // 发送商品分词发生变化的消息
        mqMessageSenderFactory.createAndSendGoodsWordMsg(word, MsgTypeEnums.GOODS_WORDS_CHANGE_MSG);

    }

    /**
     * 更新指定商品的商品分词
     * @param word 分词
     * @param id 主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWords(String word, Long id) {
        // 查询是否存在该分词

        QueryWrapper<GoodsWordsDO> queryWrapper = new QueryWrapper<GoodsWordsDO>()
                .eq("words", word)
                .ne("id", id);

        Integer count = this.goodsWordsMapper.selectCount(queryWrapper);
        if (count > 0) {
            return;
        }

        UpdateWrapper<GoodsWordsDO> updateWrapper = new UpdateWrapper<GoodsWordsDO>()
                .set("words", word)
                .set("quanpin", PinYinUtil.getPingYin(word))
                .set("szm", PinYinUtil.getPinYinHeadChar(word))
                .eq("id", id);

        // 更新分词相关信息
        goodsWordsMapper.update(new GoodsWordsDO(), updateWrapper);

        // 发送商品分词发生变化的消息
        mqMessageSenderFactory.createAndSendGoodsWordMsg(word, MsgTypeEnums.GOODS_WORDS_CHANGE_MSG);

    }

    /**
     * 更新商品分词的排序值
     * @param id 主键
     * @param sort 排序
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSort(Long id, Integer sort) {
        if (sort == null || sort < 0 || sort > 999999) {
            throw new ServiceException(GoodsErrorCode.E310.code(), "优先级范围值[0-999999],请重新输入");
        }
        this.goodsWordsMapper.update(new GoodsWordsDO(), new UpdateWrapper<GoodsWordsDO>()
                .set("sort", sort)
                .eq("id", id));
    }


    @Override
    public WebPage listPage(Long pageNo, Long pageSize, String keyword) {

        IPage iPage = this.goodsWordsMapper.selectPage(new Page<>(pageNo, pageSize), new QueryWrapper<GoodsWordsDO>()
                .select("id", "words", "quanpin", "sort", "type", "goods_num")
                .and(!StringUtils.isEmpty(keyword), e -> {
                    e.like("words", keyword).or().like("quanpin", keyword);
                })
                .orderByDesc("sort", "id"));

        return PageConvert.convert(iPage);
    }

    /**
     * 删除商品分词
     * @param goodsWordsType 分词类型
     * @param id 主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(GoodsWordsType goodsWordsType, Long id) {
        if (GoodsWordsType.SYSTEM.equals(goodsWordsType)) {
            this.goodsWordsMapper.update(new GoodsWordsDO(),
                    new UpdateWrapper<GoodsWordsDO>()
                            .set("goods_num", 0)
                            .eq("type", goodsWordsType.name()));
        } else {
            this.goodsWordsMapper.deleteById(id);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String words) {

        this.goodsWordsMapper.reduceGoodsNum(words);
    }

    /**
     * 新增商品分词
     * @param words 分词
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addWords(String words) {

        //查询同名的分词
        Integer count = this.goodsWordsMapper.selectCount(new QueryWrapper<GoodsWordsDO>().eq("words", words));

        if (count <= 0) {
            //不存在，则添加
            GoodsWordsDO goodsWordsDO = new GoodsWordsDO();
            goodsWordsDO.setGoodsNum(1L);
            goodsWordsDO.setQuanpin(PinYinUtil.getPingYin(words));
            goodsWordsDO.setSort(0);
            goodsWordsDO.setSzm(PinYinUtil.getPinYinHeadChar(words));
            goodsWordsDO.setType(GoodsWordsType.SYSTEM.name());
            goodsWordsDO.setWords(words);

            this.goodsWordsMapper.insert(goodsWordsDO);
        } else {
            //存在则增加数量
            this.goodsWordsMapper.addGoodsNum(words);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsNum(String words) {
        // 匹配已上架且审核通过的商品数量
        Integer goodsNum = goodsMapper.selectCount(new QueryWrapper<GoodsDO>()
                .like("goods_name", words)
                .eq("market_enable", 1)
                .eq("is_auth", 1)
        );

        UpdateWrapper<GoodsWordsDO> updateWrapper = new UpdateWrapper<GoodsWordsDO>()
                .set("goods_num", goodsNum)
                .eq("words", words);

        goodsWordsMapper.update(new GoodsWordsDO(), updateWrapper);
    }

    /**
     * 批量更新商品数量
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchUpdateGoodsNum() {
        //变更所有管理员添加的提示词相关商品数量   商品添加 或者修改时使用
        List<String> list = goodsWordsMapper.selectWordsList(GoodsWordsType.PLATFORM.name());
        list.forEach(this::updateGoodsNum);
    }
}
